package com.ksj.Utils.SpringUtil;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class SpringBeanUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    private static ConfigurableEnvironment ce;
    private static Set<String> standardSources = new HashSet(Arrays.asList("systemProperties", "systemEnvironment", "jndiProperties", "servletConfigInitParams", "servletContextInitParams"));

    /**
     * 设置applicationContext
     * 覆盖ApplicationContextAware方法
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringBeanUtils.applicationContext = applicationContext;
        ce = ((ConfigurableApplicationContext) SpringBeanUtils.applicationContext).getEnvironment();
    }


    public static String getProperty(String propertyName) {

        return ce.getProperty(propertyName);
    }

    public static Map<String,Object> getMainConfig(){
        return extract(ce.getPropertySources());
    }

    /**
     * 获取applicationContext
     *
     * @return applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 根据bean名称获取bean
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 根据bean class获取bean
     *
     * @param clazz
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 根据bean名称和bean class获取bean
     *
     * @param name
     * @param clazz
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    private  static Map<String, Object> extract(MutablePropertySources propertySources) {
        Map<String, Object> result = new HashMap();
        List<PropertySource<?>> sources = new ArrayList();
        Iterator var4 = propertySources.iterator();

        PropertySource source;
        while(var4.hasNext()) {
            source = (PropertySource)var4.next();
            sources.add(0, source);
        }

        var4 = sources.iterator();

        while(var4.hasNext()) {
            source = (PropertySource)var4.next();
            if (!standardSources.contains(source.getName())) {
                extract(source,result);

            }
        }

        return result;
    }

    private static void extract(PropertySource<?> parent, Map<String, Object> result) {
        if (parent instanceof CompositePropertySource) {
            try {
                List<PropertySource<?>> sources = new ArrayList();
                Iterator var4 = ((CompositePropertySource)parent).getPropertySources().iterator();

                PropertySource source;
                while(var4.hasNext()) {
                    source = (PropertySource)var4.next();
                    sources.add(0, source);
                }

                var4 = sources.iterator();

                while(var4.hasNext()) {
                    source = (PropertySource)var4.next();
                    extract(source, result);
                }
            } catch (Exception var7) {
                return;
            }
        } else if (parent instanceof EnumerablePropertySource) {
            String[] var8 = ((EnumerablePropertySource)parent).getPropertyNames();
            int var9 = var8.length;

            for(int var10 = 0; var10 < var9; ++var10) {
                String key = var8[var10];
                result.put(key, parent.getProperty(key));
            }
        }

    }

}
